﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.MathLib
{
    public class Ellipse3d : Curve3d
    {
        public override Curve3dType Type => Curve3dType.Ellipse3d;
        public bool IsClockwise { get; set; }
        public Vector3 Center { get; set; }
        public Vector3 Normal { get; set; }
        public double Rotation { get; set; }
        public double RadiusX { get; set; }
        public double RadiusY { get; set; }
        public double StartAngle { get; set; } = 0;
        public double EndAngle { get; set; } = System.Math.PI * 2;
        public Ellipse3d()
        {
        }
        public override Curve3d Clone()
        {
            var result = new Ellipse3d();
            result.Copy(this);
            return result;
        }

        public override void Copy(Curve3d src)
        {
            var srcE = src as Ellipse3d;
            this.Center = srcE.Center;
            this.Rotation = srcE.Rotation;
            this.RadiusX = srcE.RadiusX;
            this.RadiusY = srcE.RadiusY;
            this.StartAngle = srcE.StartAngle;
            this.EndAngle = srcE.EndAngle;
            this.Normal = srcE.Normal;
        }
        public override Curve3d Translate(Vector3 offset)
        {
            this.Center.Add(offset);
            return this;
        }
        public override List<Vector3> GetPoints(int div = 32)
        {
            if (div <= 0)
            {
                var radius = Math.Max(this.RadiusX, this.RadiusY);
                div = (int)Math.Ceiling(radius  * Utils.TwoPI / (this.EndAngle - this.StartAngle));
                if (div < 5)
                    div = 5;
            }
            var axis = new Vector3(0, 0, 1).Cross(this.Normal).Normalize();
            var angle = new Vector3(0, 0, 1).AngleTo(this.Normal);
            var mat1 = new Matrix4();
            mat1.MakeRotationAxis(axis, angle);
            var mat2 = new Matrix4();
            mat2.MakeTranslation(this.Center.X, this.Center.Y, this.Center.Z);
            var result = new List<Vector3>();
            for (int i = 0; i <= div; i++)
            {
                var delta = (double)i / div;
                var point2d = Ellipse2d.getEllipsePoint(new Vector2(), this.RadiusX, this.RadiusY, this.StartAngle, this.EndAngle, this.Rotation, false, delta);
                result.Add(point2d.ToVector3());
            } 
            return result.Select(n => n.ApplyMatrix4(mat1).ApplyMatrix4(mat2)).ToList();
        }
 
    }
}
